package client;

import utils.CommonUtils;

import java.io.IOException;
import java.io.InputStream;
import java.net.Socket;
import java.util.Properties;

/**
 * 服务器连接
 */
public class Server {

    public static String HOST = "";
    public static int PORT = 0;

    /**
     * 客户端与服务器保持连接的全局唯一socket
     */
    public static Socket ServerSocket;

    static {
        try {
            Properties properties = new Properties();
            InputStream in = CommonUtils.readResourceFile("server.properties");
            properties.load(in);
            HOST = properties.getProperty("host");
            PORT = Integer.valueOf(properties.getProperty("port"));
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public static void setServerAddress(String host, int port) {
        HOST = host;
        PORT = port;
    }

    public static Socket getServerConnectSocket() throws IOException {
        if (ServerSocket == null) {
            ServerSocket = new Socket(HOST, PORT);
            System.out.println("服务器已连接......");
        }
        return ServerSocket;
    }

    /**
     * 异步重连
     */
    public static void reConnect() {
        new Thread(() -> {
            if (ServerSocket == null || isServerClosed(ServerSocket)) {
                System.out.println("服务器重新连接中......");
                try {
                    ServerSocket = new Socket(HOST, PORT);
                } catch (IOException e) {
                    System.out.println("服务器重新连接失败！");
                    e.printStackTrace();
                }
                System.out.println("服务器连接成功");
            }
        }).start();
    }

    /**
     * 判断是否断开连接，断开返回true,没有返回false
     *  isClosed()、isConnected()这些方法都是本地端的方法，socket通信中一方关闭连接并不会自动告知对方
     *  因此只能通过发送数据来检测
     *  这个方法不能频繁调用，会导致连接被关闭!
     *  参考文章：https://blog.csdn.net/m0_37852667/article/details/84583857
     */
    public static Boolean isServerClosed(Socket socket){
        try{
            socket.sendUrgentData(0xFF);//发送1个字节的紧急数据，默认情况下，服务器端没有开启紧急数据处理，不影响正常通信
            return false;
        }catch(Exception se){
            return true;
        }
    }
}
